#ifndef __DALELIB_SVGWRITER_H__
#define __DALELIB_SVGWRITER_H__

#include <dalelib/graphics.h>
#include <fstream>
#include <vector>
using namespace std;

namespace dalelib
{

class SVGWriter
{
private:

	ofstream _file;

	string _fill_colour;
	string _stroke_colour;
	float _stroke_width;
//	v2 _translation;
//	float _rotation; // in degrees

public:

	SVGWriter()
		: _fill_colour(string("none"))
		, _stroke_colour(string("#000"))
		, _stroke_width(0.f)
	{ }

	~SVGWriter() { if( _file.is_open() ) close(); }

	// ********************************* accessor functions ****************************************
	ofstream& getFile() { return _file; } // should probably do some operater overloading here
	string& getFillColour() { return _fill_colour; }
	string& getStrokeColour() { return _stroke_colour; }
	float& getStrokeWidth() { return _stroke_width; }
//	v2& getTranslation() { return _translation; }
//	float& getRotation() { return _rotation; }

	// ********************************* file functions ****************************************
	void open(const string _FileName)
	{
		ofstream myfile;
		_file.open(_FileName.c_str());
		_file << "<?xml version=\"1.0\" standalone=\"no\"?>" << endl;
		_file << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">" << endl;
		_file << "<svg width=\"100%\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">" << endl;
	}

	void close()
	{
		_file << "</svg>" << endl;
		_file.close();
	}

	// ********************************* write attibute functions ****************************************
	void writePos(const v2 _Pos) { _file << "x=\"" << _Pos[0] << "\" y=\"" << _Pos[1] << "\" "; }
	void writeFillColour() { if(_fill_colour.length()) _file << "fill=\"" << _fill_colour << "\" "; }
	void writeStrokeColour() { if(_stroke_colour.length()) _file << "stroke=\"" << _stroke_colour << "\" "; }
	void writeFontSize(const int _FontSize) { _file << "font-size = \"" << _FontSize << "\" "; }
	void writeStrokeWidth() { if(_stroke_width>0.f) { _file << "stroke-width=\"" << _stroke_width << "\" "; } }
//	void writeTransform() { _file << "transform=\"translate(" << _translation[0] << " " << _translation[1] << ") rotate(" << _rotation << ")\" "; }


	// ********************************* set attibute functions ****************************************
	void setFillColour(const string _Colour) { _fill_colour = _Colour; }
	void setStrokeColour(const string _Colour) { _stroke_colour = _Colour; }

	// ********************************* draw functions ****************************************
	void drawText(const v2 _Pos,const string _String,const int _FontSize)
	{
		_file << "<text ";
		writePos(_Pos);
		writeFillColour();
		writeStrokeColour();
		writeFontSize(_FontSize);
		_file << "/>" << endl;
		_file << _String;
		_file << "</text>" << endl;
	}

	void drawLine(const v2 _Start,const v2 _End)
	{
		_file << "<line ";
		_file << "x1=\"" << _Start[0] << "\" ";
		_file << "y1=\"" << _Start[1] << "\" ";
		_file << "x2=\"" << _End[0] << "\" ";
		_file << "y2=\"" << _End[1] << "\" ";
		writeFillColour();
		writeStrokeColour();
		writeStrokeWidth();
		_file << "/>" << endl;
	}

	void drawBox(const v2 _Pos,const v2 _Rad,const v2 _Size)
	{
		_file << "<rect ";
		writePos(_Pos);
		_file << "rx=\"" << _Rad[0] << "\" ry=\"" << _Rad[1] << "\" ";
		_file << "width=\"" << _Size[0] << "\" height=\"" << _Size[1] << "\" ";
		writeFillColour();
		writeStrokeColour();
		_file << "/>" << endl;
	}

	void drawCircle(const v2 _Pos,const float _Radius)
	{
		_file << "<circle ";
		_file << "cx=\"" << _Pos[0] << "\" ";
		_file << "cy=\"" << _Pos[1] << "\" ";
		_file << "r=\"" << _Radius << "\" ";
		writeFillColour();
		writeStrokeColour();
		writeStrokeWidth();
		_file << "/>" << endl;
	}

	void drawEllipse(const v2 _Pos,const float _Angle,const v2 _Radius)
	{
		_file << "<ellipse  ";
		_file << "transform=\"translate(" << _Pos[0] << " "<< _Pos[1] << ") rotate(" << _Angle << ")\" ";
		_file << "rx=\"" << _Radius[0] << "\" ";
		_file << "ry=\"" << _Radius[1] << "\" ";
		writeFillColour();
		writeStrokeColour();
		writeStrokeWidth();
		_file << "/>" << endl;
	}

	void drawQuadraticCurve(const v2 _Start,const v2 _Mid,const v2 _End)
	{
		v2 mid = _Mid-_Start, end = _End-_Start;
		_file << "<path id=\"quadcurveABC\" d=\"M ";
		_file << _Start[0] << " " << _Start[1] << " q ";
		_file << mid[0] << " " << mid[1] << " ";
		_file << end[0] << " " << end[1] << "\" ";
		writeFillColour();
		writeStrokeColour();
		writeStrokeWidth();
		_file << "/>" << endl;
	}

	void startCurve()
	{
//		_file << "<path stroke=\"#000\" stroke-width=\"4\" fill=\"none\"" << endl;
//		_file << "   d=\"M " << p0[0][0] << "," << p0[0][1] << endl;
	}

	void addCurvePoint()
	{
//		v2 m = (p0[i].xy()+p0[i+1].xy())*0.5f;
//		myfile << "      Q  " << p0[i][0] << "," << p0[i][1] << "  " << m[0] << "," << m[1] << endl;
	}

	void endCurve()
	{
//		_file << " />" << endl;
	}

	// ********************************* helper functions ****************************************
	string convertColourToSVGString(const v3 _Colour)
	{
		char s[8];
		int r = int(_Colour[0]*16); if(r>15) r=15;
		int g = int(_Colour[1]*16); if(g>15) g=15;
		int b = int(_Colour[2]*16); if(b>15) b=15;
		sprintf(s,"#%.1x%.1x%.1x",r,g,b);
		string str = string(s);
		return str;
	}

};

} // namespace dalelib

#endif // __DALELIB_SVGWRITER_H__
